package app

import (
	"bufio"
	"errors"
	"os"
	"path/filepath"
	"regexp"

	"github.com/saintfish/chardet"
	"github.com/wailsapp/wails/v2/pkg/runtime"
	"golang.org/x/text/encoding/simplifiedchinese"
)

func copyTxt(filepath string) (name string, cnt int, err error) {

	name, ext := pathProc(filepath)
	if ext != ".txt" {
		err = errors.New(filepath + " is not a txt file")
		return
	}

	all := make([]string, 0)
	// 读取txt文件
	file, err := os.Open(filepath)
	if err != nil {
		return
	}
	defer file.Close()

	// /** 识别文件编码 **/
	reader := bufio.NewReader(file)
	b, err := reader.Peek(4096) // Peek at the first 1024 bytes
	if err != nil {
		return
	}
	// Detect the encoding
	result, err := chardet.NewTextDetector().DetectBest(b)
	if err != nil {
		return
	}
	useTrans := true
	// 判断result.Charset是否以GB开头
	if result.Charset[:2] == "GB" || result.Charset[:2] == "gb" {
		useTrans = true
	} else if result.Charset[:3] == "UTF" || result.Charset[:3] == "utf" {
		useTrans = false
	} else {
		err = errors.New("Unknown encoding: " + result.Charset)
		return
	}

	_, err = file.Seek(0, 0)
	if err != nil {
		return
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		var line string
		if useTrans {
			src := scanner.Text()
			buffer := make([]byte, len([]byte(src))*2)
			n, _, _ := simplifiedchinese.GB18030.NewDecoder().Transform(buffer, []byte(src), true)
			line = string(buffer[:n])
		} else {
			line = scanner.Text()
		}
		// 删除所有空行
		if line != "" {
			all = append(all, line)
			cnt++
		}
	}
	err = scanner.Err()
	if err != nil {
		return
	}

	// 在当前目录下创建新的txt文件
	// 检查目录是否存在，如果不存在则创建
	_, err = os.Stat("download")
	if os.IsNotExist(err) {
		err = os.Mkdir("download", 0755)
		if err != nil {
			return
		}
	}
	newFile, err := os.Create("download/" + name + ext)
	if err != nil {
		return
	}
	defer newFile.Close()
	writer := bufio.NewWriter(newFile)
	for _, line := range all {
		writer.WriteString(line + "\n")
	}
	writer.Flush()
	return
}

func pathProc(path string) (name string, ext string) {
	filenameWithExt := filepath.Base(path)
	ext = filepath.Ext(filenameWithExt)                       // 获取后缀
	name = filenameWithExt[0 : len(filenameWithExt)-len(ext)] // 去掉后缀
	return
}

type Dir struct {
	Label string
	Index int
}

func procBook(book Book) (BookFast, error) {
	path := "download/" + book.Name + ".txt"
	// 读取txt文件
	file, err := os.Open(path)
	if err != nil {
		return BookFast{}, err
	}
	defer file.Close()

	dirs := make([]Dir, 0)
	full := make([]string, 0)

	cnt := 0
	curDirIdx := -1
	scanner := bufio.NewScanner(file)
	// /第[一二三四五六七八九十百千万零〇0-9]+(章|卷)/
	re := regexp.MustCompile(`第[一二三四五六七八九十百千万零〇0-9]+(章|卷)`)
	for scanner.Scan() {
		line := scanner.Text()
		if re.MatchString(line) {
			dir := Dir{Label: line, Index: cnt}
			dirs = append(dirs, dir)
			if cnt <= book.LastLine {
				curDirIdx = len(dirs) - 1
			}
		}
		full = append(full, line)
		cnt++
	}
	err = scanner.Err()
	if err != nil {
		return BookFast{}, err
	}

	dirsLen := len(dirs)
	if dirsLen == 0 {
		return BookFast{}, errors.New("no chapter found")
	}
	var curContent []string
	var start int
	if curDirIdx == -1 {
		curContent = full[:dirs[0].Index]
		start = 0
	} else if curDirIdx == dirsLen-1 {
		curDir := dirs[curDirIdx]
		curContent = full[curDir.Index:]
		start = curDir.Index
	} else {
		curDir := dirs[curDirIdx]
		nextDir := dirs[curDirIdx+1]
		curContent = full[curDir.Index:nextDir.Index]
		start = curDir.Index
	}
	go func() {
		runtime.EventsEmit(App.Ctx, "book-full", BookAfterProc{
			Book: book,
			Full: full,
		})
	}()
	return BookFast{Book: book, Dirs: dirs, Content: curContent, FullLen: len(full), ContentStart: start}, nil
}
